<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Exercises
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora168.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora170.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Exercises</H2>
The three proposed exercises manipulate file descriptors,
processes, respectively pipes and signals. The first two exercises
stem from Unix system programming. The Objective CAML code can be compared
with the C code in the Unix or Linux distributions.<BR>
<BR>
<A NAME="toc254"></A>
<H3> Counting Words: the <TT>wc</TT> Command</H3>
We want to (re)program the Unix <TT>wc</TT> command, which
counts the number of lines, words or characters contained in
a text file. Words are separated by a space character,
a tab, or a carriage return. We do not count the separators.
<OL type=1>
<LI>
 Write a first version (<TT><A id="a287__1_APPEND/PScor.ml.tex" href="javascript: void showMessage('1_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 1,APPEND/PScor.ml.tex,wc1 -->wc1</SPAN></A></TT>)  
of the command, which only handles a single file. The name of the file
is passed as an argument on the command line.
<!-- POPUP DEFINITION -->
<layer id="l__1_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","1_APPEND/PScor.ml.tex","");
// --></script><span style="">
 On d�finit une liste de s�parateurs ainsi que trois variables
globales qui serviront aux diff�rents comptages.


<PRE><BR># <B>let</B><CODE> </CODE>seps<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>" \t"</CODE><CODE> </CODE>;;<BR><CODE>val seps : string = " \t"</CODE><BR># <B>let</B><CODE> </CODE>nl<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val nl : int ref = {contents=0}</CODE><BR># <B>let</B><CODE> </CODE>nw<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val nw : int ref = {contents=0}</CODE><BR># <B>let</B><CODE> </CODE>nc<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val nc : int ref = {contents=0}</CODE><BR>

</PRE>

La fonction <TT>counts</TT> est charg�e du comptage d'une ligne.


<PRE><BR># <B>let</B><CODE> </CODE>counts<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>was_sep<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><B>true</B><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>String.length<CODE> </CODE>s<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE>n<CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_sep<CODE> </CODE><CODE>=</CODE><CODE> </CODE>String.contains<CODE> </CODE>seps<CODE> </CODE>s<CODE>.[</CODE>i<CODE>]</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>is_sep<CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT>not<CODE> </CODE><CODE>!</CODE>was_sep<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE>incr<CODE> </CODE>nw<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>was_sep<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>is_sep<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>not<CODE> </CODE><CODE>!</CODE>was_sep<CODE> </CODE><B>then</B><CODE> </CODE>incr<CODE> </CODE>nw<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>nc<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>!</CODE>nc<CODE>+</CODE>n<CODE>+</CODE><CODE>1</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>incr<CODE> </CODE>nl<CODE> </CODE>;;<BR><CODE>val counts : string -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

La fonction <TT>count</TT> it�re la fonction de comptage d'une ligne
sur l'ensemble des lignes d'un fichier.


<PRE><BR># <B>let</B><CODE> </CODE>count<CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>nl<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>0</CODE>;<CODE> </CODE>nw<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>0</CODE>;<CODE> </CODE>nc<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>0</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f_in<CODE> </CODE><CODE>=</CODE><CODE> </CODE>open_in<CODE> </CODE>f<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>counts<CODE> </CODE><TT>(</TT>input_line<CODE> </CODE>f_in<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>End_of_file<CODE> </CODE>-&gt;<CODE> </CODE>close_in<CODE> </CODE>f_in<CODE> </CODE>;;<BR><CODE>val count : string -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

La fonction principale appelle la fonction de comptage sur le nom de
fichier pass� en argument et affiche les r�sultats.


<PRE><BR># <B>let</B><CODE> </CODE>print_count()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE>"\t%d"</CODE><CODE> </CODE><CODE>!</CODE>nl<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE>"\t%d"</CODE><CODE> </CODE><CODE>!</CODE>nw<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE>"\t%d\n"</CODE><CODE> </CODE><CODE>!</CODE>nc<CODE> </CODE>;;<BR><CODE>val print_count : unit -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>main()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>Array.length<CODE> </CODE>Sys.argv<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE>print_string<CODE> </CODE><CODE>"wc1: missing file name\n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><TT>(</TT><CODE> </CODE>count<CODE> </CODE>Sys.argv<CODE>.</CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><CODE> </CODE>;<CODE> </CODE>print_count()<CODE> </CODE><TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>e<CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"wc1: %s\n"</CODE><CODE> </CODE><TT>(</TT>Printexc.to_string<CODE> </CODE>e<TT>)</TT><CODE> </CODE>;;<BR><CODE>val main : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("1_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script>
<LI> Write a more elaborated version (<TT><A id="a288__2_APPEND/PScor.ml.tex" href="javascript: void showMessage('2_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 2,APPEND/PScor.ml.tex,wc2 -->wc2</SPAN></A></TT>), 
which can handle the three options <TT>-l</TT>, <TT>-c</TT>, <TT>-w</TT> 
as well as several file names. The options indicate if we want to
count the number of lines, characters or words. The output of
each result shall be preceded by the name of the file.
<!-- POPUP DEFINITION -->
<layer id="l__2_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","2_APPEND/PScor.ml.tex","");
// --></script><span style="">
 On reprend les variables globales et les fonctions <TT>counts</TT> et 
<TT>count</TT> de la question pr�c�dente. <BR>
<BR>
On se donne trois variable globales donnant le statut des trois
options possibles.


<PRE><BR># <B>let</B><CODE> </CODE>l_opt<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><B>false</B><CODE> </CODE><BR><CODE> </CODE><B>and</B><CODE> </CODE>w_opt<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><B>false</B><BR><CODE> </CODE><B>and</B><CODE> </CODE>c_opt<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><B>false</B><CODE> </CODE>;;<BR><CODE>val l_opt : bool ref = {contents=false}</CODE><BR><CODE>val w_opt : bool ref = {contents=false}</CODE><BR><CODE>val c_opt : bool ref = {contents=false}</CODE><BR>

</PRE>

On red�finit l'affichage en fonction du statut des options.


<PRE><BR># <B>let</B><CODE> </CODE>print_count<CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"%s:"</CODE><CODE> </CODE>f<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>l_opt<CODE> </CODE><B>then</B><CODE> </CODE>Printf.printf<CODE>"\t%d"</CODE><CODE> </CODE><CODE>!</CODE>nl<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>w_opt<CODE> </CODE><B>then</B><CODE> </CODE>Printf.printf<CODE>"\t%d"</CODE><CODE> </CODE><CODE>!</CODE>nw<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>c_opt<CODE> </CODE><B>then</B><CODE> </CODE>Printf.printf<CODE>"\t%d"</CODE><CODE> </CODE><CODE>!</CODE>nc;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline()<CODE> </CODE>;;<BR><CODE>val print_count : string -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

La ligne de commande est analys�e pour mettre � jour le statut des
options ainsi que la liste des fichiers � traiter.


<PRE><BR># <B>let</B><CODE> </CODE>f_list<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><TT>(</TT><CODE>[]:</CODE>string<CODE> </CODE>list<TT>)</TT><CODE> </CODE>;;<BR><CODE>val f_list : string list ref = {contents=[]}</CODE><BR><BR># <B>let</B><CODE> </CODE>read_args<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>usage_msg<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"wc2 [-l] [-w] [-w] files..."</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>add_f<CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE>f_list<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>f<CODE>::!</CODE>f_list<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>spec_list<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE><TT>(</TT><CODE>"-l"</CODE><CODE>,</CODE><CODE> </CODE>Arg<CODE>.</CODE>Set<CODE> </CODE>l_opt<CODE>,</CODE><CODE> </CODE><CODE>"affichage nombre de lignes"</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>"-w"</CODE><CODE>,</CODE><CODE> </CODE>Arg<CODE>.</CODE>Set<CODE> </CODE>w_opt<CODE>,</CODE><CODE> </CODE><CODE>"affichage nombre de mots"</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>"-c"</CODE><CODE>,</CODE><CODE> </CODE>Arg<CODE>.</CODE>Set<CODE> </CODE>c_opt<CODE>,</CODE><CODE> </CODE><CODE>"affichage nombre de caract�res"</CODE><TT>)</TT><CODE> </CODE><CODE>]</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Arg.parse<CODE> </CODE>spec_list<CODE> </CODE>add_f<CODE> </CODE>usage_msg<CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><BR><CODE>val read_args : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

La fonction principale it�re le comptage sur la liste des fichiers.


<PRE><BR># <B>let</B><CODE> </CODE>main()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>try</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>read_args()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.iter<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>f<CODE> </CODE>-&gt;<CODE> </CODE>count<CODE> </CODE>f;<CODE> </CODE>print_count<CODE> </CODE>f<TT>)</TT><CODE> </CODE><CODE>!</CODE>f_list<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>e<CODE> </CODE>-&gt;<CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"wc2: %s\n"</CODE><CODE> </CODE><TT>(</TT>Printexc.to_string<CODE> </CODE>e<TT>)</TT><CODE> </CODE>;;<BR><CODE>val main : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("2_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script></OL><A NAME="toc255"></A>
<H3> Pipes for Spell Checking</H3>
This exercise uses pipes to concatenate a suite of actions.
Each action takes the result of the preceding action as
argument. The communication is realized by pipes,
connecting the output of one process to the input of the
following, in the style of the Unix command line symbol
<CODE>|</CODE> .<BR>
<BR>
<OL type=1>
<LI>
 Write a function <TT><A id="a289__3_APPEND/PScor.ml.tex" href="javascript: void showMessage('3_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 3,APPEND/PScor.ml.tex,pipe2 -->pipe_two_progs</SPAN></A></TT> 
of type <I>string * string list -&gt; string * string list -&gt; unit</I>
such that <EM>pipe_two_progs (p1,[a1; ...; an])</EM>
<EM>(p2,[b1; ...; bp])</EM> starts the programs <EM>p1 a1 ... an</EM> and <EM>p2 b1
... bp</EM>, redirecting the standard output of <EM>p1</EM>
to the standard input of <EM>p2</EM>. ai and
bi are the command line arguments of each program.
<!-- POPUP DEFINITION -->
<layer id="l__3_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","3_APPEND/PScor.ml.tex","");
// --></script><span style="">
 Voici une fa�on tr�s ``&nbsp;unixienne&nbsp;'' d'implanter cette fonction.


<PRE><BR># <B>let</B><CODE> </CODE>pipe_two_progs<CODE> </CODE><TT>(</TT>p1<CODE>,</CODE><CODE> </CODE>args1<TT>)</TT><CODE> </CODE><TT>(</TT>p2<CODE>,</CODE><CODE> </CODE>args2<TT>)</TT><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>in2<CODE>,</CODE><CODE> </CODE>out1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.pipe()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>in2<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>Unix.stdout<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<TT>(</TT>Unix.dup<CODE> </CODE>out1<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>out1<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.execvp<CODE> </CODE>p1<CODE> </CODE><TT>(</TT>Array.of_list<CODE> </CODE>args1<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>out1<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>Unix.stdin<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<TT>(</TT>Unix.dup<CODE> </CODE>in2<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>in2<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.execvp<CODE> </CODE>p2<CODE> </CODE><TT>(</TT>Array.of_list<CODE> </CODE>args2<TT>)</TT><CODE> </CODE>;;<BR><CODE>val pipe_two_progs : string * string list -&gt; string * string list -&gt; unit =</CODE><BR><CODE>  &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("3_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> We revisit the <A id="a290__4_APPEND/PScor.ml.tex" href="javascript: void showMessage('4_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 4,APPEND/PScor.ml.tex,orthographe -->spell checker</SPAN></A> function  
from the exercise on page <A HREF="book-ora041.html#exo-ortho">??</A> to write a first program.
Modify it so that the list of faulty words is sent without treatment
in the form of one line per word to the standard output.
<!-- POPUP DEFINITION -->
<layer id="l__4_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","4_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>orthographe<CODE> </CODE>dico<CODE> </CODE>nom<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE>open_in<CODE> </CODE>nom<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>input_line<CODE> </CODE>f<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>ls<CODE> </CODE><CODE>=</CODE><CODE> </CODE>mots<CODE> </CODE>s<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.iter<CODE> </CODE><TT>(</TT>Printf.printf<CODE>"%s\n"</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>verifie<CODE> </CODE>dico<CODE> </CODE>ls<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>failwith<CODE> </CODE><CODE>"cas impossible"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>End_of_file<CODE> </CODE>-&gt;<CODE> </CODE>close_in<CODE> </CODE>f<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>close_in<CODE> </CODE>f<CODE> </CODE>;<CODE> </CODE>raise<CODE> </CODE>x<CODE> </CODE><CODE> </CODE>;;<BR><CODE>val orthographe : arbre_lex -&gt; string -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("4_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> 
The second <A id="a291__5_APPEND/PScor.ml.tex" href="javascript: void showMessage('5_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 5,APPEND/PScor.ml.tex,sort -->program</SPAN></A> takes a sequence of character strings 
from its standard input and sorts it in lexicographical order.
The function <TT>Sort.list</TT> can be used, which sorts a list in
an order defined by a given predicate. The sorted list is written to
the standard output.
<!-- POPUP DEFINITION -->
<layer id="l__5_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","5_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>trie<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>[]<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><CODE> </CODE>l<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>Sort.list<CODE> </CODE><TT>(</TT><CODE>&lt;</CODE><TT>)</TT><CODE> </CODE><TT>(</TT><TT>(</TT>input_line<CODE> </CODE>stdin<TT>)</TT><CODE>::!</CODE>l<TT>)</TT><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>End_of_file<CODE> </CODE>-&gt;<CODE> </CODE>List.iter<CODE> </CODE><TT>(</TT>Printf.printf<CODE>"%s\n"</CODE><TT>)</TT><CODE> </CODE><CODE>!</CODE>l<CODE> </CODE>;;<BR><CODE>val trie : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("5_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> <A id="a292__6_APPEND/PScor.ml.tex" href="javascript: void showMessage('6_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 6,APPEND/PScor.ml.tex,pipe_test -->Test</SPAN></A> the function <TT>pipe_two_progs</TT> 
with the two programs.<BR>
<BR>

<LI> Write a function <TT><A id="a293__7_APPEND/PScor.ml.tex" href="javascript: void showMessage('7_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 7,APPEND/PScor.ml.tex,pipen -->pipe_n_progs</SPAN></A></TT> 
to connect a list of programs.
<!-- POPUP DEFINITION -->
<layer id="l__6_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","6_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># pipe_two_progs<CODE> </CODE><TT>(</TT><CODE>"orthographe"</CODE><CODE>,[</CODE><CODE>""</CODE>;Sys.argv<CODE>.</CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><CODE>]</CODE><TT>)</TT><CODE> </CODE><TT>(</TT><CODE>"tri"</CODE><CODE>,[]</CODE><TT>)</TT><CODE> </CODE>;;<BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("6_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<!-- POPUP DEFINITION -->
<layer id="l__7_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","7_APPEND/PScor.ml.tex","");
// --></script><span style="">
 Pour all�ger un peu l'�criture on se donne deux fonctions de
redirection de l'entr�e et de la sortie standard.


<PRE><BR># <B>let</B><CODE> </CODE>dup_stdin<CODE> </CODE>in_descr<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>in_descr<CODE>&lt;&gt;</CODE>Unix.stdin<CODE> </CODE><B>then</B><CODE> </CODE>Unix.dup2<CODE> </CODE>in_descr<CODE> </CODE>Unix.stdin<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>in_descr<CODE> </CODE>;;<BR><CODE>val dup_stdin : Unix.file_descr -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>dup_stdout<CODE> </CODE>out_descr<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>out_descr<CODE>&lt;&gt;</CODE>Unix.stdout<CODE> </CODE><B>then</B><CODE> </CODE>Unix.dup2<CODE> </CODE>out_descr<CODE> </CODE>Unix.stdout<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>out_descr<CODE> </CODE>;;<BR><CODE>val dup_stdout : Unix.file_descr -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

Pour it�rer le pipeline, on d�finit une fonction r�cursive
dont le premier argument donne le canal d'entr�e du premier
processus � cha�ner.


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>pipe_n_progs_loop<CODE> </CODE>in_descr<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE>p<CODE>,</CODE>args<CODE>]</CODE><CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>dup_stdin<CODE> </CODE>in_descr<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.execvp<CODE> </CODE>p<CODE> </CODE><TT>(</TT>Array.of_list<CODE> </CODE>args<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><TT>(</TT>p<CODE>,</CODE>args<TT>)</TT>::ps<CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>in2<CODE>,</CODE><CODE> </CODE>out1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Unix.pipe()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><B>match</B><CODE> </CODE>Unix.fork()<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>in2<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>dup_stdin<CODE> </CODE>in_descr<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>dup_stdout<CODE> </CODE>out1<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.execvp<CODE> </CODE>p<CODE> </CODE><TT>(</TT>Array.of_list<CODE> </CODE>args<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Unix.close<CODE> </CODE>out1<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>pipe_n_progs_loop<CODE> </CODE>in2<CODE> </CODE>ps<CODE> </CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val pipe_n_progs_loop :</CODE><BR><CODE>  Unix.file_descr -&gt; (string * string list) list -&gt; unit = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>pipe_n_progs<CODE> </CODE>ps<CODE> </CODE><CODE>=</CODE><CODE> </CODE>pipe_n_progs_loop<CODE> </CODE>Unix.stdin<CODE> </CODE>ps<CODE> </CODE>;;<BR><CODE>val pipe_n_progs : (string * string list) list -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("7_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write a <A id="a294__8_APPEND/PScor.ml.tex" href="javascript: void showMessage('8_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 8,APPEND/PScor.ml.tex,rmdup -->program</SPAN></A> to suppress 
multiple occurrences of elements in a list.
<!-- POPUP DEFINITION -->
<layer id="l__8_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","8_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>rmdup<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>[]<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>input_line<CODE> </CODE>stdin<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>not<CODE> </CODE><TT>(</TT>List.mem<CODE> </CODE>x<CODE> </CODE><CODE>!</CODE>l<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE>l<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>x<CODE>::!</CODE>l<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>End_of_file<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>List.iter<CODE> </CODE><TT>(</TT>Printf.printf<CODE>"%s\n"</CODE><TT>)</TT><CODE> </CODE><CODE>!</CODE>l<CODE> </CODE>;;<BR><CODE>val rmdup : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("8_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> <A id="a295__9_APPEND/PScor.ml.tex" href="javascript: void showMessage('9_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 9,APPEND/PScor.ml.tex,pipe_test_2 -->Test</SPAN></A> the function <TT>pipe_n_progs</TT>  
with these three programs. 
<!-- POPUP DEFINITION -->
<layer id="l__9_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","9_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># pipe_n_progs<CODE> </CODE><CODE>[</CODE><CODE> </CODE><TT>(</TT><CODE>"orthographe"</CODE><CODE>,[</CODE><CODE>""</CODE>;Sys.argv<CODE>.</CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><CODE>]</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>"tri"</CODE><CODE>,[]</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>"rmdup"</CODE><CODE>,[]</CODE><TT>)</TT><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("9_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script></OL><A NAME="toc256"></A>
<H3> Interactive Trace</H3>
In a complex calculation it may be useful to interact with the
program to verify the progression. For this purpose we revisit the
exercise on page <A HREF="book-ora078.html#exo-eratosthene">??</A> on the computation
of prime numbers contained in an interval.
<OL type=1>
<LI>
 <A id="a296__10_APPEND/PScor.ml.tex" href="javascript: void showMessage('10_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 10,APPEND/PScor.ml.tex,modif-era -->Modify</SPAN></A> the program so that a global 
variable <TT>result</TT> always contains the last prime
number found.
<!-- POPUP DEFINITION -->
<layer id="l__10_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","10_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>result<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val result : int ref = {contents=0}</CODE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>eras<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>[]<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>p::q<CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>result<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>p<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>p<CODE> </CODE>::<CODE> </CODE><TT>(</TT>eras<CODE> </CODE><TT>(</TT>List.filter<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><B>mod</B><CODE> </CODE>p<CODE> </CODE><CODE>&lt;&gt;</CODE><CODE> </CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>q<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>val eras : int list -&gt; int list = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("10_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> Write a function <TT><A id="a297__11_APPEND/PScor.ml.tex" href="javascript: void showMessage('11_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 11,APPEND/PScor.ml.tex,siginthandle -->sigint_handle</SPAN></A></TT> 
which handles the signal <TT>sigint</TT> and writes the content of
<TT>result</TT> to the output.
<!-- POPUP DEFINITION -->
<layer id="l__11_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","11_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># <B>let</B><CODE> </CODE>sigint_handle<CODE> </CODE><TT>(</TT><CODE>_</CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>Printf.printf<CODE>"Current prime number : %d\n"</CODE><CODE> </CODE><CODE>!</CODE>result;<BR><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><CODE>val sigint_handle : int -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("11_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> <A id="a298__12_APPEND/PScor.ml.tex" href="javascript: void showMessage('12_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 12,APPEND/PScor.ml.tex,modif-sigint -->Modify</SPAN></A> the default signal handling 
of <TT>sigint</TT> by associating with it the preceding function
<TT>sigint_handle</TT>. 
<!-- POPUP DEFINITION -->
<layer id="l__12_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","12_APPEND/PScor.ml.tex","");
// --></script><span style="">
 

<PRE><BR># Sys.set_signal<CODE> </CODE>Sys.sigint<CODE> </CODE><TT>(</TT>Sys<CODE>.</CODE>Signal_handle<CODE> </CODE>sigint_handle<TT>)</TT><CODE> </CODE>;;<BR><CODE>- : unit = ()</CODE><BR>

</PRE>

</span><script language="JavaScript"><!--
  closePopUp("12_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script><BR>
<BR>

<LI> <A id="a299__13_APPEND/PScor.ml.tex" href="javascript: void showMessage('13_APPEND/PScor.ml.tex')" class="mousable"><SPAN style=""><!-- 13,APPEND/PScor.ml.tex,modif-compile -->Compile</SPAN></A> the program, then start the 
executable with an upper bound for the computation time.
During the computation, send the signal <TT>sigint</TT> to
the process, by the Unix <TT>kill</TT> command as well as by the 
key combination <TT>CTRL-C</TT>. 
<!-- POPUP DEFINITION -->
<layer id="l__13_APPEND/PScor.ml.tex" class="hint" style="visibility:hidden; position:absolute" visibility="hide"  width="50%">
<script language="JavaScript"><!--
  openPopUp("50%","13_APPEND/PScor.ml.tex","");
// --></script><span style="">
 <PRE>
$ ocamlc premiers.ml
$ premiers 15000
Current prime number : 2539
Current prime number : 8263
2 3 5 7 11 13 17 19 23 29 31 37 41 43 ............
</PRE></span><script language="JavaScript"><!--
  closePopUp("13_APPEND/PScor.ml.tex");
// --></script></layer><!-- END OF POPUP -->
<script language="JavaScript"><!--
  initializePreviousHints();
// --></script></OL><HR>
<A HREF="book-ora168.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora170.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
